<template>
	<view class="pay-method">
		<view class="pay-item" v-for="item in state.payMethodList" :key="item.id" @click="handleSelectPay(item)">
			<view class="name-box">
				<image class="img" :src="handlePayMethodImg(item.code)"></image>
				<view class="name">
					<view class="tit">{{ item.name }}</view>
					<view class="memo balance" v-if="item.code === PayMethodCodeEnum.balancepay">
						当前余额：￥{{ props.userInfo?.balance || 0 }}元</view>
					<view class="memo" v-else>{{ item.memo }}</view>
				</view>
			</view>
			<view class="icon-select">
				<image class="icon" v-if="state.payCode === item.code"
					:src="handleStaticResources('/static/images/icon/cart-select-on.png')"></image>
				<image class="icon" v-else :src="handleStaticResources('/static/images/icon/cart-select.png')"></image>
			</view>
		</view>
	</view>
</template>
<script setup lang="ts">
	import { Ref, reactive, watch } from 'vue';
	import { PayMethodCodeEnum, PaymentTypeEnum } from '@/core/enum';
	import { handleStaticResources, handleShowToast, handleRouteRedirectTo } from '@/core/utils';
	import type { PayMethodListType, Response } from '@/core/models';
	import { queryPay } from '@/core/api';

	const props = withDefaults(defineProps<{
		payMethodList : Array<PayMethodListType>,
		orderType : PaymentTypeEnum,
		orderId : number,
		recharge : number,
		userInfo : any,
	}>(), {
		payMethodList: () => [],
		orderType: PaymentTypeEnum.common,
		orderId: 0, /** 如果是商品订单此参数必须 */
		recharge: 0, /** 如果是充值订单此参数必须 */
		userInfo: {},
	});

	const emits = defineEmits(['handleSelectPay']);

	const state = reactive<{
		payCode : string;
		payMethodList : Array<PayMethodListType>;
	}>({
		payCode: '',
		payMethodList: [],
	})

	watch(() => props.payMethodList, (newVal : Array<PayMethodListType>) => {
		if (newVal.length > 0) {
			let payMethodList : Array<PayMethodListType> = newVal;

			// #ifdef MP-WEIXIN
			payMethodList = newVal.filter(item => item.code !== PayMethodCodeEnum.alipay);
			// #endif

			// #ifdef MP-ALIPAY
			payMethodList = newVal.filter(item => item.code !== PayMethodCodeEnum.wechatpay);
			// #endif

			if (props.orderType === PaymentTypeEnum.recharge) {
				payMethodList = payMethodList.filter(item => item.code !== 'balancepay' || !item.isOnline);
			}

			/** 当支付方式只有一个的时候，默认选择 */
			if (payMethodList.length == 1) {
				state.payCode = payMethodList[0].code;
				emits('handleSelectPay', payMethodList[0].code);
			}
			state.payMethodList = payMethodList;
		}
	})

	/** 选择支付类型 */
	const handleSelectPay = (item : PayMethodListType) => {
		if (item.code != state.payCode) {
			state.payCode = item.code;
			emits('handleSelectPay', state.payCode);
		}
	}
	/** 返回支付类型图标 */
	const handlePayMethodImg = (code : string) => {
		let url : string = '';
		switch (code) {
			case PayMethodCodeEnum.balancepay:
				url = '/static/images/pay/balancepay.png';
				break;
			case PayMethodCodeEnum.wechatpay:
				url = '/static/images/pay/wechatpay.png';
				break;
			case PayMethodCodeEnum.alipay:
				url = '/static/images/pay/alipay.png';
				break;
			case PayMethodCodeEnum.offline:
				url = '/static/images/pay/offline.png';
				break;
			default:
				url = '/static/images/pay/balancepay.png';
		};
		return handleStaticResources(url);
	}

	/** 判断是商品订单 */
	const isGoodsOrder = () => {
		return (
			props.orderType === PaymentTypeEnum.common ||
			props.orderType === PaymentTypeEnum.pinTuan ||
			props.orderType === PaymentTypeEnum.group ||
			props.orderType === PaymentTypeEnum.seckill ||
			props.orderType === PaymentTypeEnum.bargain ||
			props.orderType === PaymentTypeEnum.giveaway ||
			props.orderType === PaymentTypeEnum.solitaire ||
			props.orderType === PaymentTypeEnum.transactionComponent ||
			props.orderType === PaymentTypeEnum.serviceOrder
		)
	}

	const handlePayNow = async (loading : Ref<boolean>) => {
		uni.showLoading({
			title: '加载中',
		});
		let data : any = {
			payment_code: state.payCode,
			payment_type: props.orderType,
			ids: isGoodsOrder() ? props.orderId : props.userInfo.id,
		}

		// #ifdef MP-WEIXIN || MP-ALIPAY
		data.params = {
			trade_type: 'JSAPI',
		}
		// #endif

		// #ifdef APP-PLUS || APP-PLUS-NVUE
		data.params = {
			trade_type: 'APP',
		}
		// #endif

		if (props.orderType === PaymentTypeEnum.recharge && props.recharge) {
			data.ids = props.recharge;
			data.params.money = props.recharge;
		} else if ((props.orderType === PaymentTypeEnum.formPay || props.orderType === PaymentTypeEnum.formOrder) && props.recharge) {
			data.ids = props.orderId;
		}

		const pay : Response<any> = await queryPay(data);
		if (pay.status) {
			if (state.payCode === PayMethodCodeEnum.wechatpay) {
				handleWxpay(pay, loading);
			} else if (state.payCode === PayMethodCodeEnum.alipay) {
				handleAlipay(pay, loading);
			} else if (state.payCode === PayMethodCodeEnum.balancepay) {
				uni.hideLoading();
				handleShowToast('支付成功', 'success', () => {
					setTimeout(() => {
						loading.value = false;
						handleRouteRedirectTo(`/pages/order/result/result?id=${pay.data.paymentId}`)
					}, 1000)
				})
			} else if (state.payCode === PayMethodCodeEnum.offline) {
				uni.hideLoading();
				loading.value = false;
				uni.showModal({
					title: '线下支付说明',
					content: '请联系客服进行线下支付',
					success: function () { }
				});
			}
		} else {
			handleShowToast(pay.msg, 'none', () => {
				loading.value = false;
				setTimeout(() => {
					uni.hideLoading();
				}, 1000);
			})
		}

	}

	/** 微信支付 */
	const handleWxpay = (res : any, loading : Ref<boolean>) => {
		uni.requestPayment({
			provider: 'wxpay',
			// #ifdef MP-WEIXIN
			timeStamp: res.data.timeStamp,
			nonceStr: res.data.nonceStr,
			package: res.data.package,
			signType: res.data.signType,
			paySign: res.data.paySign,
			// #endif

			// #ifdef APP-PLUS || APP-PLUS-NVUE
			orderInfo: {
				appid: res.data.appid,
				noncestr: res.data.noncestr,
				package: res.data.package,
				partnerid: res.data.partnerid,
				prepayid: res.data.prepayid,
				timestamp: res.data.timestamp,
				sign: res.data.sign,
			},
			// #endif

			success: function (e : any) {
				uni.hideLoading();
				// #ifdef MP-WEIXIN
				if (e.errMsg === 'requestPayment:ok') {
					handleShowToast('支付成功', 'success', () => {
						setTimeout(() => {
							loading.value = false;
							handleRouteRedirectTo(`/pages/order/result/result?id=${res.data.paymentId}`)
						}, 1000)
					})
				}
				// #endif

				// #ifdef APP-PLUS || APP-PLUS-NVUE
				handleShowToast('支付成功', 'success', () => {
					setTimeout(() => {
						loading.value = false;
						handleRouteRedirectTo(`/pages/order/result/result?id=${res.data.paymentId}`)
					}, 1000)
				})
				// #endif 
			},
			fail: function (e : any) {
				loading.value = false;
				if (e.errMsg === 'requestPayment:fail cancel') {
					handleShowToast('您已经取消此方式支付,可继续选择其他方式支付。');
				}
				setTimeout(function () {
					uni.hideLoading();
				}, 1000);
			}
		});
	}

	/** 支付宝支付 */
	const handleAlipay = (res : any, loading : Ref<boolean>) => {
		uni.requestPayment({
			provider: 'alipay',
			orderInfo: res.data.tradeNo,
			success: function (e : any) {
				// #ifdef MP-ALIPAY
				if (e.errMsg === 'requestPayment:ok') {
					handleShowToast('支付成功', 'success', () => {
						setTimeout(() => {
							loading.value = false;
							handleRouteRedirectTo(`/pages/order/result/result?id=${res.data.paymentId}`)
						}, 1000)
					})
				}
				// #endif

				// #ifdef APP-PLUS || APP-PLUS-NVUE
				handleShowToast('支付成功', 'success', () => {
					setTimeout(() => {
						loading.value = false;
						handleRouteRedirectTo(`/pages/order/result/result?id=${res.data.paymentId}`)
					}, 1000)
				})
				// #endif 
			},
			fail: function (res) {
				loading.value = false;
				console.log(res);
			}
		});
	}

	/** 把支付方法暴露出去 */
	defineExpose({
		handlePayNow,
	})
</script>
<style lang="scss" scoped>
	@import './index.scss';
</style>